package multiagent

import (
	"anders-cli/internal/ai"
	"anders-cli/internal/config"
	"anders-cli/pkg/logger"
	"context"
	"fmt"
	"os"
	"sync"
	"time"
)

// MultiAgentManager 多Agent管理器
type MultiAgentManager struct {
	// 模式管理
	currentMode string // "expert" 或 "team"
	mu          sync.RWMutex

	// 专家模式
	expertBackend ai.Backend

	// 团队模式
	projectManager *ProjectManager
	agents         []Agent

	// 配置
	cfg *config.Config
}

// NewMultiAgentManager 创建多Agent管理器
func NewMultiAgentManager() (*MultiAgentManager, error) {
	cfg := config.Get()

	// 创建AI后端
	expertBackend, err := ai.NewBackend()
	if err != nil {
		return nil, err
	}

	manager := &MultiAgentManager{
		currentMode:   cfg.MultiAgent.DefaultMode,
		expertBackend: expertBackend,
		cfg:           cfg,
	}

	// 如果默认是团队模式，初始化团队
	if cfg.MultiAgent.DefaultMode == "team" {
		manager.initializeTeam()
	}

	return manager, nil
}

// GetCurrentMode 获取当前模式
func (m *MultiAgentManager) GetCurrentMode() string {
	m.mu.RLock()
	defer m.mu.RUnlock()
	return m.currentMode
}

// SetMode 设置模式
func (m *MultiAgentManager) SetMode(mode string) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	if mode != "expert" && mode != "team" {
		return &InvalidModeError{mode: mode}
	}

	oldMode := m.currentMode
	m.currentMode = mode

	// 如果切换到团队模式，初始化团队
	if mode == "team" && m.projectManager == nil {
		m.initializeTeam()
	}

	logger.Info("模式切换: %s -> %s", oldMode, mode)
	return nil
}

// ProcessQuery 处理用户查询
func (m *MultiAgentManager) ProcessQuery(query string, ctx map[string]any) (string, int, string) {
	return m.ProcessQueryWithReasoning(query, ctx, nil)
}

// ProcessQueryWithReasoning 处理用户查询并支持推理过程显示
func (m *MultiAgentManager) ProcessQueryWithReasoning(query string, ctx map[string]any, reasoningCallback func(string)) (string, int, string) {
	// 从配置获取超时时间
	timeout := time.Duration(m.cfg.MultiAgent.QueryTimeout) * time.Second
	if timeout <= 0 {
		timeout = 30 * time.Second // 默认30秒
	}

	// 创建超时上下文
	queryCtx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()

	// 创建带超时的查询处理
	type result struct {
		response   string
		confidence int
		feedback   string
		err        error
	}

	resultChan := make(chan result, 1)

	go func() {
		m.mu.RLock()
		mode := m.currentMode
		m.mu.RUnlock()

		var response string
		var confidence int
		var feedback string
		var err error

		switch mode {
		case "expert":
			response, confidence, feedback = m.processExpertMode(query, ctx, reasoningCallback)
		case "team":
			response, confidence, feedback = m.processTeamMode(query, ctx, reasoningCallback)
		default:
			err = fmt.Errorf("未知模式: %s", mode)
		}

		resultChan <- result{
			response:   response,
			confidence: confidence,
			feedback:   feedback,
			err:        err,
		}
	}()

	// 等待结果或超时
	select {
	case res := <-resultChan:
		if res.err != nil {
			return "", 0, res.err.Error()
		}
		return res.response, res.confidence, res.feedback
	case <-queryCtx.Done():
		return "", 0, "查询超时，请稍后重试"
	}
}

// processExpertMode 处理专家模式查询
func (m *MultiAgentManager) processExpertMode(query string, context map[string]any, reasoningCallback func(string)) (string, int, string) {
	// 检查后端是否支持推理过程
	var response string
	var err error

	// 尝试使用带推理的查询方法
	if backend, ok := m.expertBackend.(interface {
		QueryWithReasoning(string, []interface{}, func(string)) (string, error)
	}); ok {
		response, err = backend.QueryWithReasoning(query, nil, reasoningCallback)
	} else {
		// 回退到普通查询
		response, err = m.expertBackend.Query(query, nil)
	}

	if err != nil {
		return "", 0, "专家模式处理失败: " + err.Error()
	}

	// 简单置信度评估
	confidence := 85
	if len(response) > 1000 {
		confidence = 90
	}

	return response, confidence, "专家模式处理完成"
}

// processTeamMode 处理团队模式查询
func (m *MultiAgentManager) processTeamMode(query string, context map[string]any, reasoningCallback func(string)) (string, int, string) {
	m.mu.RLock()
	pm := m.projectManager
	m.mu.RUnlock()

	if pm == nil {
		return "", 0, "团队模式未初始化"
	}

	return pm.Process(query, context)
}

// GetModeStatus 获取模式状态信息
func (m *MultiAgentManager) GetModeStatus() string {
	m.mu.RLock()
	defer m.mu.RUnlock()

	status := "当前模式: " + m.currentMode + "\n"

	if m.currentMode == "expert" {
		if m.expertBackend != nil {
			status += "专家AI: " + m.expertBackend.Name() + "\n"
		} else {
			status += "专家AI: 未初始化\n"
		}
	} else if m.currentMode == "team" {
		if m.projectManager != nil {
			status += "项目管理器: 已初始化\n"
			status += fmt.Sprintf("子Agent数量: %d\n", len(m.agents))
			status += fmt.Sprintf("最大反馈轮次: %d\n", m.cfg.MultiAgent.MaxFeedbackRounds)
		} else {
			status += "项目管理器: 未初始化\n"
		}
	}

	return status
}

// GetAvailableCommands 获取可用命令列表
func (m *MultiAgentManager) GetAvailableCommands() []string {
	return []string{
		"/expert - 切换到专家模式（单一AI响应）",
		"/team - 切换到团队模式（多Agent协作）",
		"/status - 查看当前模式状态",
		"/report - 生成最终报告文件",
	}
}

// GenerateReport 生成最终报告文件
func (m *MultiAgentManager) GenerateReport(task string, response string, confidence int, feedback string) error {
	timestamp := time.Now().Format("2006-01-02_15-04-05")
	filename := fmt.Sprintf("multiagent_report_%s.md", timestamp)

	report := fmt.Sprintf(`# 多Agent协作报告

## 基本信息
- **生成时间**: %s
- **任务**: %s
- **模式**: %s
- **置信度**: %d%%

## 任务详情
%s

## 反馈总结
%s

## 详细响应
%s

---
*此报告由Anders-CLI多Agent系统自动生成*
`, time.Now().Format("2006-01-02 15:04:05"), task, m.currentMode, confidence, task, feedback, response)

	err := os.WriteFile(filename, []byte(report), 0644)
	if err != nil {
		return fmt.Errorf("写入报告文件失败: %v", err)
	}

	logger.Info("多Agent报告已生成: %s", filename)
	return nil
}

// initializeTeam 初始化团队模式
func (m *MultiAgentManager) initializeTeam() {
	logger.Info("初始化多Agent团队...")

	// 创建子Agent
	m.agents = CreateDefaultAgents(m.expertBackend)

	// 创建项目管理器（支持角色配置）
	pm, err := CreateProjectManagerFromConfig(m.expertBackend)
	if err != nil {
		logger.Error("创建项目管理器失败: %v，使用默认实现", err)
		pm = NewProjectManager(
			m.expertBackend,
			m.cfg.MultiAgent.MaxFeedbackRounds,
			m.cfg.MultiAgent.ConflictThreshold,
		)
	}
	m.projectManager = pm

	// 添加子Agent到项目管理器
	for _, agent := range m.agents {
		m.projectManager.AddAgent(agent)
		logger.Info("已添加子Agent: %s", agent.GetName())
	}

	logger.Info("多Agent团队初始化完成，共 %d 个子Agent", len(m.agents))
}

// InvalidModeError 无效模式错误
type InvalidModeError struct {
	mode string
}

func (e *InvalidModeError) Error() string {
	return "无效模式: " + e.mode + " (支持: expert, team)"
}

// ProjectState 项目状态结构体
type ProjectState struct {
	Mode           string                 `json:"mode"`
	Context        map[string]interface{} `json:"context"`
	TaskLogs       []string               `json:"task_logs"`
	GanttTasks     []GanttTask            `json:"gantt_tasks"`
	LastTask       string                 `json:"last_task"`
	LastResponse   string                 `json:"last_response"`
	LastConfidence int                    `json:"last_confidence"`
	LastFeedback   string                 `json:"last_feedback"`
	Paused         bool                   `json:"paused"`       // 是否暂停
	PauseReason    string                 `json:"pause_reason"` // 暂停原因
}

// GanttTask Gantt任务结构体
type GanttTask struct {
	ID        string `json:"id"`
	Name      string `json:"name"`
	AgentRole string `json:"agent_role"`
	Status    string `json:"status"`
	Progress  int    `json:"progress"`
	Phase     string `json:"phase"`
}

// SaveProjectState 保存项目状态到数据库
func (m *MultiAgentManager) SaveProjectState(projectName string) error {
	m.mu.RLock()
	defer m.mu.RUnlock()

	logger.Info("保存项目状态: %s", projectName)

	// 构建项目状态
	state := ProjectState{
		Mode:        m.currentMode,
		Context:     make(map[string]interface{}),
		TaskLogs:    []string{},
		GanttTasks:  []GanttTask{},
		Paused:      false,
		PauseReason: "",
	}

	// 如果有项目管理器，获取其状态
	if m.projectManager != nil {
		// TODO: 从项目管理器获取更详细的状态信息
		logger.Info("项目管理器存在，包含更多状态信息")
	}

	// 保存到数据库
	// TODO: 这里将在后续实现中集成数据库保存功能
	logger.Info("项目状态已准备保存 (数据库集成将在后续实现): mode=%s", state.Mode)

	return nil
}

// LoadProjectState 从数据库加载项目状态
func (m *MultiAgentManager) LoadProjectState(projectName string) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	logger.Info("加载项目状态: %s", projectName)

	// TODO: 从数据库加载项目状态
	logger.Info("项目状态加载功能将在后续实现")

	return nil
}

// PauseProject 暂停项目
func (m *MultiAgentManager) PauseProject(reason string) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	if m.currentMode != "team" {
		return fmt.Errorf("只能在团队模式下暂停项目")
	}

	logger.Info("暂停项目，原因: %s", reason)

	// TODO: 实现实际的暂停逻辑
	// 这里可以设置项目管理器的暂停状态

	return nil
}

// ResumeProject 恢复项目
func (m *MultiAgentManager) ResumeProject() error {
	m.mu.Lock()
	defer m.mu.Unlock()

	if m.currentMode != "team" {
		return fmt.Errorf("只能在团队模式下恢复项目")
	}

	logger.Info("恢复项目继续执行")

	// TODO: 实现实际的恢复逻辑

	return nil
}

// GetProjectStatus 获取项目状态信息
func (m *MultiAgentManager) GetProjectStatus() string {
	m.mu.RLock()
	defer m.mu.RUnlock()

	status := fmt.Sprintf("当前模式: %s\n", m.currentMode)

	if m.currentMode == "team" {
		if m.projectManager != nil {
			status += "项目管理器: 活跃\n"
			status += fmt.Sprintf("子Agent数量: %d\n", len(m.agents))
		} else {
			status += "项目管理器: 未初始化\n"
		}
	}

	return status
}
